package com.sscl.baselibrary.exts

import com.sscl.baselibrary.utils.ConversionUtil
import com.sscl.baselibrary.utils.ConversionUtil.getUnsignedByte
import java.nio.ByteBuffer
import java.nio.charset.Charset
import java.nio.charset.CodingErrorAction
import java.util.Locale


/**
 * ByteArrayExt
 *
 * Byte数组扩展函数
 * @author jackie Penghe
 * @date 2024/9/4
 */


/**
 * MAC地址的长度
 */
private const val ADDRESS_BYTE_LENGTH = 6

/**
 * Long类型字节数组最大值
 */
private const val MAX_LONG_BYTE_ARRAY_LENGTH = 8


/**
 * 字节数组转十六进制字符串，每个字节间用空格分割
 */
fun ByteArray?.toHexStringWithSpace(): String? {
    return toHexStringWithDelimiter(" ")
}

/**
 * 字节数组转十六进制字符串，每个字节间用指定分隔符分割
 */
fun ByteArray?.toHexStringWithDelimiter(delimiter: String): String? {
    this ?: return null
    var stmp: String
    val sb = StringBuilder()
    for (aByte in this) {
        stmp = Integer.toHexString(aByte.toInt() and 0xFF)
        sb.append(if (stmp.length == 1) "0$stmp" else stmp)
        sb.append(delimiter)
    }
    var result = sb.toString().uppercase(Locale.getDefault())
    result = result.substring(0, result.length - delimiter.length)
    return result
}

/**
 * 字节数组转MAC地址字符串
 */
fun ByteArray?.toMacAddressString(): String? {
    if (this?.size != ADDRESS_BYTE_LENGTH) {
        return null
    }
    val toHexStringWithSpace = toHexStringWithSpace() ?: return null
    val addressCache = toHexStringWithSpace.replace(" ", ":")
    return addressCache.uppercase(Locale.getDefault())
}

/**
 * byte数组转为long
 *
 * @return long
 */
fun ByteArray?.toLong(): Long? {
    this ?: return null
    val length = size
    val byteBits = 8
    if (isEmpty() || size > MAX_LONG_BYTE_ARRAY_LENGTH) {
        throw RuntimeException("byteArray length must be in range 1 ~ 8")
    }
    var cache: Long = 0
    for (i in 0 until length) {
        val aByte: Byte = get(i)
        val unsignedByte: Int = ConversionUtil.getUnsignedByte(aByte)
        cache = cache or unsignedByte.toLong() shl (byteBits * (length - i - 1))
    }
    return cache
}

/**
 * 将一个byte数组拼接为一个int型数
 *
 * @param byteArray byte数组长度不超过4
 * @return int型数
 */
fun ByteArray.byteArrayToInt(): Int {
    val length = size
    val maxIntByteArrayLength = 4
    val byteBits = 8
    if (this.isEmpty() || length > maxIntByteArrayLength) {
        throw RuntimeException("byteArray length must be in range 1 ~ 4")
    }
    var cache = 0
    for (i in 0 until length) {
        val aByte: Byte = this[i]
        val unsignedByte: Int = getUnsignedByte(aByte)
        cache = cache or unsignedByte shl (byteBits * (length - i - 1))
    }
    return cache
}

/**
 * 判断字节数组是否包含乱码
 *
 * @param charset 字符集
 */
fun ByteArray.containsGarbledChars(charset: Charset = Charsets.UTF_8): Boolean {
    try {
        // 创建CharsetDecoder并设置为严格模式
        val decoder = charset.newDecoder()
            .onMalformedInput(CodingErrorAction.REPORT)
            .onUnmappableCharacter(CodingErrorAction.REPORT)

        // 尝试解码字节数组
        decoder.decode(ByteBuffer.wrap(this))
        return false
    } catch (e: CharacterCodingException) {
        // 如果解码过程中出现异常，说明包含乱码
        return true
    }
}